home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume6 / redir < prev    next >
Encoding:
Text File  |  1989-02-03  |  11.5 KB  |  340 lines

  1. Path: lll-winken!ames!mailrus!tut.cis.ohio-state.edu!ucbvax!unisoft!uunet!allbery
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Newsgroups: comp.sources.misc
  4. Subject: v06i031: redir - redirect stdout and stderr separately
  5. Message-ID: <48160@uunet.UU.NET>
  6. Date: 4 Feb 89 03:12:04 GMT
  7. Sender: allbery@uunet.UU.NET
  8. Reply-To: bobg+@andrew.cmu.edu
  9. Lines: 328
  10. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  11.  
  12. Posting-number: Volume 6, Issue 31
  13. Submitted-by: bobg+@andrew.cmu.edu
  14. Archive-name: redir
  15.  
  16. This is redir, a simple Unix program for csh(1) users who are tired of being
  17. sneered at by their sh(1)-using brothers because their shell can't separate
  18. stdout from stderr.  Redir will exec a program you name, redirecting the
  19. standard output and/or the standard error (or neither) according to redir's
  20. options.  Previously, the only good way of separating stdout from stderr in csh
  21. was something like
  22.  
  23.         (command > stdout-destination) >& stderr-destination
  24.  
  25. which stinks.  Suppose you wanted to pipe command A through command B,
  26. collecting the stderr of A in A.err and the stderr of B in B.err, while
  27. displaying the stdout of B?  What would you do then, huh?  Probably something
  28. awful that looks like this:
  29.  
  30.         (A | (B > /dev/tyy) >& B.err) >& A.err
  31.  
  32. I'm not even sure that would work.  I am sure that this works:
  33.  
  34.         redir -e A.err A | redir -e B.err B
  35.  
  36. Well, here it is.
  37.  
  38. ----- Not this line -----
  39. #! /bin/sh
  40. # This is a shell archive.  Remove anything before this line, then unpack
  41. # it by saving it into a file and typing "sh file".  To overwrite existing
  42. # files, type "sh file -c".  You can also feed this as standard input via
  43. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  44. # will see the following message at the end:
  45. #               "End of shell archive."
  46. # Contents:  README Makefile redir.c redir.doc
  47. # Wrapped by bobg@ephrata.andrew.cmu.edu on Sun Jan 29 19:02:42 1989
  48. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  49. if test -f README -a "${1}" != "-c" ; then
  50.   echo shar: Will not over-write existing file \"README\"
  51. else
  52. echo shar: Extracting \"README\" \(893 characters\)
  53. sed "s/^X//" >README <<'END_OF_README'
  54. XRedir is a simple utility which remedies a problem in csh(1);
  55. Xnamely, that you can't redirect stdout and stderr separately,
  56. Xas you can in sh(1), unless you want to do something ugly like
  57. X
  58. X       (command > stdout) >& stderr
  59. X
  60. XRedir will execute the command you name, with stdout and
  61. Xstderr redirected according to the options you supply to redir.
  62. XThe file redir.doc gives the usage of this program.
  63. X
  64. XTo compile this program, type "make redir".  To install this
  65. Xprogram on your system, modify the Makefile so that the
  66. Xvariables BIN and DOC are defined to be the pathnames
  67. Xof the directories to hold the binary file "redir" and the
  68. Xdocumentation file "redir.doc," respectively, then type
  69. X"make install".
  70. X
  71. XThis software exists in the public domain.  Absolutely no
  72. Xrestrictions on its usage, modification or distribution
  73. Xexist.  No guarantees are made concerning the proper
  74. Xfunctioning of this software.
  75. END_OF_README
  76. if test 893 -ne `wc -c <README`; then
  77.     echo shar: \"README\" unpacked with wrong size!
  78. fi
  79. # end of overwriting check
  80. fi
  81. if test -f Makefile -a "${1}" != "-c" ; then
  82.   echo shar: Will not over-write existing file \"Makefile\"
  83. else
  84. echo shar: Extracting \"Makefile\" \(350 characters\)
  85. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  86. XOPTIMIZE = -O
  87. XDEBUG =
  88. XINCLUDES =
  89. XPROFILE =
  90. XLIBS =
  91. XCFLAGS = $(OPTIMIZE) $(DEBUG) $(INCLUDES) $(PROFILE)
  92. XCC = cc
  93. XBIN =
  94. XDOC =
  95. X
  96. XTARGET = redir
  97. X
  98. Xredir: redir.c
  99. X       $(CC) $(CFLAGS) -o redir redir.c
  100. X
  101. Xtest: $(TARGET)
  102. X
  103. Xinstall: $(TARGET)
  104. X       cp $(TARGET) $(BIN)
  105. X       -strip $(BIN)/$(TARGET)
  106. X       cp redir.doc $(DOC)
  107. X
  108. Xclean:
  109. X       -rm -f *.BAK *.CKP *.o a.out gmon.out $(TARGET)
  110. END_OF_Makefile
  111. if test 350 -ne `wc -c <Makefile`; then
  112.     echo shar: \"Makefile\" unpacked with wrong size!
  113. fi
  114. # end of overwriting check
  115. fi
  116. if test -f redir.c -a "${1}" != "-c" ; then
  117.   echo shar: Will not over-write existing file \"redir.c\"
  118. else
  119. echo shar: Extracting \"redir.c\" \(3851 characters\)
  120. sed "s/^X//" >redir.c <<'END_OF_redir.c'
  121. X/* redir
  122. X * a program to execute a command, redirecting stdout and stderr separately,
  123. X * a feature available in sh but not csh.
  124. X *
  125. X * THIS SOFTWARE EXISTS IN THE PUBLIC DOMAIN.  ABSOLUTELY NO
  126. X * RESTRICTIONS ON ITS USAGE, MODIFICATION OR DISTRIBUTION
  127. X * EXIST.  NO GUARANTEES ARE MADE CONCERNING THE PROPER
  128. X * FUNCTIONING OF THIS SOFTWARE.
  129. X *
  130. X * Usage:
  131. X *
  132. X * redir [options] command-words...
  133. X *
  134. X * where options are
  135. X *  -o file
  136. X *   to redirect stdout to file "file," without clobbering "file" if it exists
  137. X *  -e file
  138. X *   to redirect stderr to file "file," without clobbering "file" if it exists
  139. X *  -O file
  140. X *   to redirect stdout to file "file," clobbering "file" if it exists
  141. X *  -E file
  142. X *   to redirect stderr to file "file," clobbering "file" if it exists
  143. X *  -a
  144. X *   the following redirection option is to append to the named file, as in:
  145. X *    redir -O foo.log -ae foo.err command command-arg1 command-arg2 ...
  146. X *   (stdout (destructively) to foo.log, stderr appended to foo.err.
  147. X *   The -a option doesn't care if the named file exists or not.  This option
  148. X *   must be used twice if you want stdout and stderr both to be appended
  149. X *   to their respective files;
  150. X *    redir -ao foo.log -ae foo.err command ...
  151. X */
  152. X
  153. X#include <stdio.h>
  154. X#include <sys/file.h>
  155. X
  156. X#define USAGESTRING ("Usage: %s [-[a][oeOE] file] ... command-words\n")
  157. X
  158. Xmain(argc, argv)
  159. Xint             argc;
  160. Xchar          **argv;
  161. X{
  162. X    extern int      optind;
  163. X    extern char    *optarg;
  164. X    char           *stderrfile = NULL, *stdoutfile = NULL;
  165. X    int             rstderr = 0, rstdout = 0, cstderr = 0, cstdout = 0, astderr
  166. = 0, astdout = 0, appendopt = 0, c, fd;
  167. X
  168. X    while ((c = getopt(argc, argv, "ao:e:O:E:")) != EOF) {
  169. X       switch (c) {
  170. X           case 'a':
  171. X               if (appendopt) {
  172. X                   fprintf(stderr, USAGESTRING, argv[0]);
  173. X                   exit(1);
  174. X               }
  175. X               ++appendopt;
  176. X               break;
  177. X           case 'e':
  178. X               if (rstderr) {
  179. X                   fprintf(stderr, USAGESTRING, argv[0]);
  180. X                   exit(1);
  181. X               }
  182. X               ++rstderr;
  183. X               stderrfile = optarg;
  184. X               if (appendopt) {
  185. X                   appendopt = 0;
  186. X                   ++astderr;
  187. X               }
  188. X               break;
  189. X           case 'o':
  190. X               if (rstdout) {
  191. X                   fprintf(stderr, USAGESTRING, argv[0]);
  192. X                   exit(1);
  193. X               }
  194. X               ++rstdout;
  195. X               stdoutfile = optarg;
  196. X               if (appendopt) {
  197. X                   appendopt = 0;
  198. X                   ++astdout;
  199. X               }
  200. X               break;
  201. X           case 'E':
  202. X               if (rstderr) {
  203. X                   fprintf(stderr, USAGESTRING, argv[0]);
  204. X                   exit(1);
  205. X               }
  206. X               ++rstderr;
  207. X               ++cstderr;
  208. X               stderrfile = optarg;
  209. X               if (appendopt) {
  210. X                   appendopt = 0;
  211. X                   ++astderr;
  212. X               }
  213. X               break;
  214. X           case 'O':
  215. X               if (rstdout) {
  216. X                   fprintf(stderr, USAGESTRING, argv[0]);
  217. X                   exit(1);
  218. X               }
  219. X               ++rstdout;
  220. X               ++cstdout;
  221. X               stdoutfile = optarg;
  222. X               if (appendopt) {
  223. X                   appendopt = 0;
  224. X                   ++astdout;
  225. X               }
  226. X               break;
  227. X           default:
  228. X               fprintf(stderr, USAGESTRING, argv[0]);
  229. X               exit(1);
  230. X               break;
  231. X       }
  232. X    }
  233. X    if (rstdout) {
  234. X       if ((fd = open(stdoutfile, (astdout ?
  235. X                                   (O_WRONLY | O_APPEND | O_CREAT) :
  236. X                                   (cstdout ?
  237. X                                    (O_WRONLY | O_CREAT | O_TRUNC) :
  238. X                                    (O_WRONLY | O_CREAT | O_EXCL))),
  239. X                      0644)) < 0) {
  240. X           fprintf(stderr,
  241. X                   "%s: couldn't open destination %s for standard output\n",
  242. X                   argv[0], stdoutfile);
  243. X           exit(2);
  244. X       }
  245. X       if (dup2(fd, 1) < 0) {
  246. X           fprintf(stderr,
  247. X                   "%s: couldn't open destination %s for standard output\n",
  248. X                   argv[0], stdoutfile);
  249. X           exit(2);
  250. X       }
  251. X       close(fd);
  252. X    }
  253. X    if (rstderr) {
  254. X       if ((fd = open(stderrfile, (astderr ?
  255. X                                   (O_WRONLY | O_APPEND | O_CREAT) :
  256. X                                   (cstderr ?
  257. X                                    (O_WRONLY | O_CREAT | O_TRUNC) :
  258. X                                    (O_WRONLY | O_CREAT | O_EXCL))),
  259. X                      0644)) < 0) {
  260. X           fprintf(stderr,
  261. X                   "%s: couldn't open destination %s for standard error\n",
  262. X                   argv[0], stderrfile);
  263. X           exit(2);
  264. X       }
  265. X       if (dup2(fd, 2) < 0) {
  266. X           fprintf(stderr,
  267. X                   "%s: couldn't open destination %s for standard error\n",
  268. X                   argv[0], stderrfile);
  269. X           exit(2);
  270. X       }
  271. X       close(fd);
  272. X    }
  273. X    execvp(argv[optind], argv + optind);
  274. X}
  275. END_OF_redir.c
  276. if test 3851 -ne `wc -c <redir.c`; then
  277.     echo shar: \"redir.c\" unpacked with wrong size!
  278. fi
  279. # end of overwriting check
  280. fi
  281. if test -f redir.doc -a "${1}" != "-c" ; then
  282.   echo shar: Will not over-write existing file \"redir.doc\"
  283. else
  284. echo shar: Extracting \"redir.doc\" \(1658 characters\)
  285. sed "s/^X//" >redir.doc <<'END_OF_redir.doc'
  286. XREDIR(1)
  287. X
  288. XNAME
  289. Xredir - redirect standard output and/or standard error (diagnostic output)
  290. X
  291. XSYNOPSIS
  292. Xredir [-[a][oeOE] file] ... command arg1 arg2 ...
  293. X
  294. XDESCRIPTION
  295. XRedir executes the named command with the given arguments,
  296. Xredirecting the standard output and/or standard input according
  297. Xto the options given.  This program exists to remedy a serious
  298. Xdeficiency in csh(1), namely that csh does not allow stdout
  299. Xand stderr to be redirected separately.  The options are:
  300. X
  301. X-o file        Redirect the standard output of the named command
  302. X       to the file "file", only if "file" does not yet exist.
  303. X-O file        Redirect the standard output of the named command
  304. X       to the file "file", clobbering the existing
  305. X       version of "file" if it exists.
  306. X-e     Redirect the standard error (diagnostic output) of the
  307. X       named command to file "file", only if "file" does not yet exist.
  308. X-E     Redirect the standard error (diagnostic output) of the
  309. X       named command to the file "file", clobbering the existing
  310. X       version of "file" if it exists.
  311. X-ao file       Append the standard output of the named command
  312. X       to the file "file", whether or not "file" exists.
  313. X-ae file       Append the standard error (diagnostic output) of the
  314. X       named command to the file "file", whether or not "file" exists.
  315. X
  316. X-aO and -aE are synonyms for -ao and -ae.
  317. X
  318. XEXAMPLE
  319. XThe following example demonstrates a means for piping the output
  320. Xof sed through ctags and then into awk; errors from ctags will be
  321. Xplaced in the file "errors":
  322. X
  323. X% ... | sed -f sed-script | redir -e errors ctags -x | awk -f awk-script | ...
  324. X
  325. XAUTHOR
  326. XBob Glickstein
  327. X       Information Technology Center
  328. X       Carnegie Mellon University
  329. X       Pittsburgh, PA
  330. X       22-Jan-89
  331. X       ARPAnet: bobg@andrew.cmu.edu
  332. END_OF_redir.doc
  333. if test 1658 -ne `wc -c <redir.doc`; then
  334.     echo shar: \"redir.doc\" unpacked with wrong size!
  335. fi
  336. # end of overwriting check
  337. fi
  338. echo shar: End of shell archive.
  339. exit 0
  340.